<?php

namespace App\Services;

use App\Enums\AssetSourceType;
use App\Enums\AssetStatus;
use App\Models\Asset;
use App\Models\BlindBoxRecord;
use Illuminate\Contracts\Cache\LockTimeoutException;
use Illuminate\Support\Arr;

class BlindBoxService
{
    /** @var WalletService */
    private $walletService;

    public function __construct(WalletService $walletService)
    {
        $this->walletService = $walletService;
    }

    /** 打开盲盒 */
    public function openBlindBox(BlindBoxRecord $record)
    {
        $assetProduct = $record->asset_product;
        $user = $record->user;
        $lock = \Cache::lock('open_blind_box' . $record->id, 60);

        try {
            $lock->block(2); // 如果获取不到锁，则等待2秒

            $transResult = $this->walletService->transfer(
                '',
                $assetProduct->contract_address,
                [$record->asset_token_id],
                $user->wallet_address
            );
            $transHash = Arr::get($transResult, $record->asset_token_id, 'trans_hash_not_return');
            $asset = new Asset();
            $asset->user_id = $user->id;
            $asset->source_type = AssetSourceType::BLIND_BOX;
            $asset->source_id = $record->id;
            $asset->contract_address = $assetProduct->contract_address;
            $asset->token_id = $record->asset_token_id;
            $asset->trans_hash = $transHash;
            $asset->asset_status = AssetStatus::HOLD;

            // 保存资产信息
            \DB::transaction(function () use ($asset, $record) {
                $asset->save();
                $record->user_asset_id = $asset->id;
                $record->open_time = now();
                $record->save();
                $record->setRelation('asset', $asset);

                return $record;
            });
        } catch (LockTimeoutException $e) {
            throw new \Exception('盲盒开启中，请稍后再试');
        } finally {
            $lock->release();
        }
    }
}
